package com.industry.examinaion.service;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.industry.examinaion.dal.dataobject.ExaminaionBank;
import com.industry.examinaion.dal.dataobject.ExaminaionPaper;
import com.industry.examinaion.dal.dataobject.ExaminaionPaperQuestion;
import com.industry.examinaion.dal.dataobject.ExaminaionQuestion;
import com.industry.examinaion.dal.db.ExaminaionQuestionMapper;
import com.industry.examinaion.dal.dto.ExamCreateRuleDto;
import com.industry.framework.core.generic.AbstractCoreGenericService;
import com.industry.system.dal.dataobject.SystemUser;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class ExaminaionBankService extends AbstractCoreGenericService<ExaminaionBank, String> {
    @Resource
    private ExaminaionQuestionMapper examinaionQuestionMapper;
    @Resource
    private ExaminaionPaperService examinaionPaperService;
    @Resource
    private ExaminaionPaperQuestionService examinaionPaperQuestionService;

    /**
     * @description: 创建试卷
     * @author: jsy
     * @time: 2025/7/5 19:58
     */
    @Transactional(rollbackFor = Exception.class)
    public void createExaminationPaper(List<ExamCreateRuleDto> createRuleDtos, String belongsUserId , String userName) {
        ExaminaionPaper examinaionPaper = new ExaminaionPaper();
        examinaionPaper.setScore(new BigDecimal("100"));
        examinaionPaper.setTitle(DateUtil.format(LocalDateTime.now(), "yyyy-MM-dd") + "生成试卷");
        examinaionPaper.setBelongsUserId(belongsUserId);//所属用户id
        examinaionPaper.setBelongsUserName(userName);
        List<String> ids = examinaionPaperService.batchInsert(Collections.singletonList(examinaionPaper));
        String examinationPaperId = ids.get(0);
        //随机创建试卷问题
        randomlyGenerateQuestions(createRuleDtos, examinationPaperId);
    }

    public void randomlyGenerateQuestions(List<ExamCreateRuleDto> createRuleDtos, String examinationPaperId) {
        List<ExaminaionQuestion> allExaminaionQuestions = new ArrayList<>();
        //根据题库的examinaionBanckId取抽取count个题目
        for (ExamCreateRuleDto createRuleDto : createRuleDtos) {
            List<ExaminaionQuestion> collect = extractQuestions(createRuleDto);
            allExaminaionQuestions.addAll(collect);
        }
        //生成试卷内容
        createPaperQuestion(allExaminaionQuestions, examinationPaperId);
    }

    public List<ExaminaionQuestion> extractQuestions(ExamCreateRuleDto createRuleDto) {
        LambdaQueryWrapper<ExaminaionQuestion> lambdaQueryWrapper = Wrappers.lambdaQuery(ExaminaionQuestion.class).eq(ExaminaionQuestion::getExaminaionBankId, createRuleDto.getExaminaionBanckId());
        Long total = examinaionQuestionMapper.selectCount(lambdaQueryWrapper);
        // 生成count个随机偏移量
        List<Long> offsets = new java.security.SecureRandom().longs(0, total)
                .distinct()
                .limit(createRuleDto.getCount())
                .boxed()
                .collect(Collectors.toList());
        // 根据偏移量获取题目
        List<ExaminaionQuestion> collect = offsets.stream()
                .map(offset -> examinaionQuestionMapper.selectList(lambdaQueryWrapper).get(Math.toIntExact(offset)))
                .collect(Collectors.toList());
        return collect;
    }

    public void createPaperQuestion(List<ExaminaionQuestion> allExaminaionQuestions, String examinationPaperId) {
        List<ExaminaionPaperQuestion> examinaionPaperQuestionList = new ArrayList<>();
        for (ExaminaionQuestion examinaionQuestion : allExaminaionQuestions) {
            ExaminaionPaperQuestion examinaionPaperQuestion = new ExaminaionPaperQuestion();
            examinaionPaperQuestion.setExaminaionPaperId(examinationPaperId);
            examinaionPaperQuestion.setExaminaionQuestionId(examinaionQuestion.getId());
            examinaionPaperQuestion.setScore(examinaionQuestion.getScore());
            examinaionPaperQuestion.setType(examinaionQuestion.getType());
            examinaionPaperQuestion.setContent(examinaionQuestion.getContent());
            examinaionPaperQuestion.setOptions(examinaionQuestion.getOptions());
            examinaionPaperQuestionList.add(examinaionPaperQuestion);
        }
        examinaionPaperQuestionService.batchInsert(examinaionPaperQuestionList);
    }
}
